class Depend {
  constructor() {
    // 优化二: 不会存在多次收集这样了
    this.reactiveFns = new Set();
  }
  addDepend(reactiveFn) {
    this.reactiveFns.add(reactiveFn);
  }
  depend() {
    if (activeReactiveFn) {
      this.addDepend(activeReactiveFn);
    }
  }
  notify() {
    this.reactiveFns.forEach((fn) => {
      fn();
    });
  }
}

const depend = new Depend();
let activeReactiveFn = null;

// 依赖收集
function watchFn(fn) {
  activeReactiveFn = fn;
  // 这里执行依次 就可以进行一个依赖 收集了
  fn();
  activeReactiveFn = null;
}

// 封装对象响应式函数
function reactive(obj) {
  return new Proxy(obj, {
    get(target, key, receiver) {
      const depend = getDepend(target, key);
      // 优化一, 封装的更彻底
      depend.depend();
      return Reflect.get(target, key, receiver);
    },
    set(target, key, newValue, receiver) {
      Reflect.set(target, key, newValue, receiver);
      const depend = getDepend(target, key);
      depend.notify();
    },
  });
}

const targetMap = new WeakMap();
// 简化班
function getDepend(target, key) {
  // 根据 target 对象 获取 map
  const map = targetMap.get(target);
  if (!map) {
    map = new Map();
    targetMap.set(target, map);
  }
  // 根据 key 获取depend 对象
  let depend = map.get(key);
  if (!depend) {
    depend = new Depend();
    map.set(key, depend);
  }
  return depend;
}

// 对象响应式, 这样写就完事了
const objProxy = reactive({
  name: "xjh",
  age: 10,
});

watchFn(function foo() {
  console.log("foo~");
});

function bar() {
  console.log("bar~~");
}

objProxy.name = "xjh2";
objProxy.name = "xjh3";
objProxy.name = "xjh4";
